using System;
using System.IO;
using System.Text;

namespace Engine.FileFormats3D.WR2TrafficFiles
{
    [Flags]
    public enum TurnType
    {
        None,
        Right,
        Forward,
        Left
    }

    public class Spline
    {
        #region Public Fields

        public short crossroad;
        public short firstRow;
        public int index;
        public short nextSpline;
        public short nLanes;
        public short nodeEnd2;
        public short nodestart1;
        public short numberOfRows;
        public short numWays;
        public short oppositeLane;
        public short previewSpline;
        public short speedBlockID;

        // perhaps it is the number of how many Lanetypes are used.
        public float StreetLength;

        public float tangentLength1;
        public float tangentLength2;
        public TurnType turnType;

        #endregion Public Fields

        #region Internal Fields

        internal int crossID;

        #endregion Internal Fields

        #region Private Fields

        private short numberOfDifferentStreettypes;
        private long positioninfile;

        #endregion Private Fields

        #region Public Constructors

        public Spline(int index, short NodeStart, short NodeEnd, short Speedblock, float tangentLength1, float tangentLength2, float streetlength, short crossroad,
            short OppositeLane, short previewSpline, short nextSpline, short numberOfWays, int crossID, TurnType turnType)
        {
            this.index = index;
            this.positioninfile = 0;

            this.nodestart1 = NodeStart;
            this.nodeEnd2 = NodeEnd;
            this.speedBlockID = Speedblock;
            this.numberOfDifferentStreettypes = 1;
            this.tangentLength1 = tangentLength1;
            this.tangentLength2 = tangentLength2;
            this.StreetLength = streetlength;
            this.nLanes = 2;
            this.crossroad = crossroad;
            this.oppositeLane = OppositeLane;
            this.previewSpline = previewSpline;
            this.nextSpline = nextSpline;
            this.numWays = numberOfWays;
            this.firstRow = -1; //8 Bytes
            this.numberOfRows = 0;

            this.crossID = crossID;
            this.turnType = turnType;
        }

        public Spline(BinaryReader br, int index)
        {
            this.index = index;
            this.positioninfile = br.BaseStream.Position;

            this.nodestart1 = br.ReadInt16();
            this.nodeEnd2 = br.ReadInt16();
            this.speedBlockID = br.ReadInt16();
            this.numberOfDifferentStreettypes = br.ReadInt16();
            this.tangentLength1 = br.ReadSingle();
            this.tangentLength2 = br.ReadSingle();
            this.StreetLength = br.ReadSingle();
            this.nLanes = br.ReadInt16();
            this.crossroad = br.ReadInt16();
            this.oppositeLane = br.ReadInt16();
            this.previewSpline = br.ReadInt16();
            this.nextSpline = br.ReadInt16();
            this.numWays = br.ReadInt16();
            this.firstRow = br.ReadInt16(); //8 Bytes
            this.numberOfRows = br.ReadInt16();
        }

        #endregion Public Constructors

        #region Public Properties

        public short SpeedBlockID { get { return speedBlockID; } set { speedBlockID = value; } }

        #endregion Public Properties

        #region Public Methods

        public void Save(BinaryWriter bw)
        {
            bw.Write(this.nodestart1);
            bw.Write(this.nodeEnd2);
            bw.Write(this.speedBlockID);
            bw.Write(this.numberOfDifferentStreettypes);
            bw.Write(this.tangentLength1);
            bw.Write(this.tangentLength2);
            bw.Write(this.StreetLength);
            bw.Write(this.nLanes);
            //if(this.crossroad == 0)
            bw.Write(this.crossroad);
            //else
            //    bw.Write((short)5);//this.crossroad);
            bw.Write(this.oppositeLane);
            bw.Write(this.previewSpline);
            bw.Write(this.nextSpline);
            //if(this.numWays == 1)
            bw.Write(this.numWays);
            //else
            //    bw.Write((short)2);//this.numWays);
            bw.Write(this.firstRow);
            bw.Write(this.numberOfRows);
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("-Spline- " + index.ToString() + " ---------- at Position: " + this.positioninfile.ToString());

            sb.AppendLine("NodeID Start       " + nodestart1.ToString());
            sb.AppendLine("NodeID End         " + nodeEnd2.ToString());
            sb.AppendLine("SpeedBlock ID      " + speedBlockID.ToString());
            sb.AppendLine("Nex??s             " + numberOfDifferentStreettypes.ToString());
            sb.AppendLine("Tangent1 Length    " + tangentLength1.ToString());
            sb.AppendLine("Tangent2 Length    " + tangentLength2.ToString());
            sb.AppendLine("StreetLength       " + StreetLength.ToString());
            sb.AppendLine("nLanes             " + nLanes.ToString());
            sb.AppendLine("Options            " + crossroad.ToString());
            sb.AppendLine("Opposite Lane      " + oppositeLane.ToString());
            sb.AppendLine("Preview Spline     " + previewSpline.ToString());
            sb.AppendLine("Next Spline        " + nextSpline.ToString());
            sb.AppendLine("Num Ways           " + numWays.ToString());
            sb.AppendLine("firstRow           " + this.firstRow.ToString());//.ToString()); //8 Bytes
            sb.AppendLine("numberOfRows       " + this.numberOfRows.ToString());

            sb.AppendLine("-end-");

            return sb.ToString();
        }

        #endregion Public Methods
    }
}